
//================================================================================================
// File Name   : chunjun_tcu_tb.sv
// Create Time : Mon Dec 16 10:00:00 2024
// Description : Simple testbench for TCU module
//================================================================================================

module chunjun_tcu_tb;

// Clock and reset
logic clk;
logic rst_n;

// TCU module instance
chunjun_tcu tcu_inst (
    .clk                        (clk),
    .rst_n                      (rst_n),
    .tcu_idle                   (),
    
    // Base addresses
    .itcm_global_base_addr      (12'h000),
    .dtcm0_global_base_addr     (12'h100),
`ifdef CHUNJUN_SUPPORT_DTCM1
    .dtcm1_global_base_addr     (12'h200),
`endif
`ifdef CHUNJUN_SUPPORT_VTCM
    .vtcm_global_base_addr      (12'h300),
`endif
    
    // PCU interface
    .pcu_csr_msyscfg           (32'h0),
    .pcu_csr_meictl            (32'h0),
    .pcu_csr_meibmap           (32'h0),
    .pcu_csr_meibmaph          (32'h0),
    
    // ICU interface - instruction fetch
    .icu_tcu_req_vld_m1        (1'b0),
    .tcu_icu_req_rdy_m1        (),
    .icu_tcu_req_addr_m1       (20'h0),
    .icu_tcu_req_route_m1      (3'h0),
    .icu_tcu_req_id_m1         (2'h0),
    .icu_tcu_flush_m2          (1'b0),
    .icu_tcu_cancel_m2         (1'b0),
    .tcu_icu_rsp_vld_m2        (),
    .icu_tcu_rsp_rdy_m2        (1'b1),
    .tcu_icu_rsp_data_m2       (),
    .tcu_icu_rsp_id_m2         (),
    .tcu_icu_rsp_id_m3         (),
    
    // LSU interface - load requests
    .lsu_tcu_ld_req_valid_m1   (2'h0),
    .tcu_lsu_ld_req_ready_m1   (),
    .lsu_tcu_ld_req_addr_m1    (40'h0),
    .lsu_tcu_ld_req_route_m1   (8'h0),
    .lsu_tcu_ld_req_size_m1    (4'h0),
    .lsu_tcu_ld_req_lsqid_m1   (12'h0),
    .lsu_tcu_ld_req_cancel_m2  (2'h0),
    .lsu_tcu_flush_valid       (1'b0),
    .lsu_tcu_flush_lsqid       (6'h0),
    .tcu_lsu_ld_rsp_valid_m2   (),
    .lsu_tcu_ld_rsp_ready_m2   (2'h3),
    .tcu_lsu_ld_rsp_data_m2    (),
    .tcu_lsu_ld_rsp_lsqid_m2   (),
    .tcu_lsu_ld_rsp_valid_m3   (),
    .tcu_lsu_ld_rsp_raserr_m3  (),
    .tcu_lsu_ld_rsp_replay_m3  (),
    .tcu_lsu_ld_rsp_lsqid_m3   (),
    
    // SBU interface - store requests
    .sbu_tcu_req_vld           (1'b0),
    .tcu_sbu_req_rdy           (),
    .sbu_tcu_req_addr          (20'h0),
    .sbu_tcu_req_route         (4'h0),
    .sbu_tcu_req_wdata         (64'h0),
    .sbu_tcu_req_wstrb         (8'h0),
    .sbu_tcu_req_atop          (6'h0),
    .sbu_tcu_req_id            (6'h0),
    .tcu_sbu_rsp_vld           (),
    .sbu_tcu_rsp_rdy           (1'b1),
    .tcu_sbu_rsp_id            (),
    .tcu_sbu_rsp_raserr        (),
    .tcu_sbu_atop_rvld         (),
    .tcu_sbu_atop_rdata        (),
    .tcu_sbu_atop_rid          (),
    .tcu_sbu_atop_raserr       (),
    
    // BMU interface
    .bmu_tcu_req_vld           (1'b0),
    .tcu_bmu_req_rdy           (),
    .bmu_tcu_req_addr          (20'h0),
    .bmu_tcu_req_route         (4'h0),
    .bmu_tcu_req_size          (3'h0),
    .bmu_tcu_req_wr            (1'b0),
    .bmu_tcu_req_wdata         (64'h0),
    .bmu_tcu_req_wstrb         (8'h0),
    .bmu_tcu_req_id            (13'h0),
    .tcu_bmu_rsp_vld           (),
    .tcu_bmu_rsp_data          (),
    .tcu_bmu_rsp_id            (),
    .tcu_bmu_rsp_raserr        (),
    
    // ITCM RAM interface
    .itcm_ram_cs               (),
    .itcm_ram_wr               (),
    .itcm_ram_addr             (),
    .itcm_ram_wen              (),
    .itcm_ram_wdata            (),
    .itcm_ram_rdata            (64'h0),
    
    // DTCM0 RAM interface - low bank
    .dtcm0_ram_lo_cs           (),
    .dtcm0_ram_lo_wr           (),
    .dtcm0_ram_lo_addr         (),
    .dtcm0_ram_lo_wen          (),
    .dtcm0_ram_lo_wdata        (),
    .dtcm0_ram_lo_rdata        (32'h0),
    
    // DTCM0 RAM interface - high bank
    .dtcm0_ram_hi_cs           (),
    .dtcm0_ram_hi_wr           (),
    .dtcm0_ram_hi_addr         (),
    .dtcm0_ram_hi_wen          (),
    .dtcm0_ram_hi_wdata        (),
    .dtcm0_ram_hi_rdata        (32'h0),
    
    // DTCM1 RAM interface - low bank
`ifdef CHUNJUN_SUPPORT_DTCM1
    .dtcm1_ram_lo_cs           (),
    .dtcm1_ram_lo_wr           (),
    .dtcm1_ram_lo_addr         (),
    .dtcm1_ram_lo_wen          (),
    .dtcm1_ram_lo_wdata        (),
    .dtcm1_ram_lo_rdata        (32'h0),
    
    // DTCM1 RAM interface - high bank
    .dtcm1_ram_hi_cs           (),
    .dtcm1_ram_hi_wr           (),
    .dtcm1_ram_hi_addr         (),
    .dtcm1_ram_hi_wen          (),
    .dtcm1_ram_hi_wdata        (),
    .dtcm1_ram_hi_rdata        (32'h0),
`endif
    
    // VTCM interface - VPU requests
`ifdef CHUNJUN_SUPPORT_V_EXT
    .vpu_vtcu_req_vld_m1       (4'h0),
    .vtcu_vpu_req_rdy_m1       (),
    .vpu_vtcu_req_wr_m1        (4'h0),
    .vpu_vtcu_req_info_m1      (20'h0),
    .vpu_vtcu_req_addr_m1      (80'h0),
    .vpu_vtcu_req_wdata_m1     (128'h0),
    .vpu_vtcu_req_wstrb_m1     (16'h0),
    .vtcu_vpu_rsp_vld_m3       (),
    .vpu_vtcu_rsp_rdy_m3       (4'hF),
    .vtcu_vpu_rsp_data_m3      (),
    .vtcu_vpu_rsp_info_m3      (),
    .vtcu_vpu_rsp_raserr_m3    (),
    
    // VTCM RAM interface
    .vtcm_ram_cs               (),
    .vtcm_ram_wr               (),
    .vtcm_ram_addr             (),
    .vtcm_ram_wen              (),
    .vtcm_ram_wdata            (),
    .vtcm_ram_rdata            (128'h0),
    
    // VPU normal TCM interface
    .vpu_tcu_ld_req_vld_m1     (2'h0),
    .tcu_vpu_ld_req_rdy_m1     (),
    .vpu_tcu_ld_req_addr_m1    (40'h0),
    .vpu_tcu_ld_req_route_m1   (6'h0),
    .vpu_tcu_ld_req_vlqid_m1   (8'h0),
    .vpu_tcu_ld_req_cancel_m2  (2'h0),
    .tcu_vpu_ld_rsp_vld_m3     (),
    .vpu_tcu_ld_rsp_rdy_m3     (2'h3),
    .tcu_vpu_ld_rsp_data_m3    (),
    .tcu_vpu_ld_rsp_vlqid_m3   (),
    .tcu_vpu_ld_rsp_raserr_m3  (),
`endif
    
    // RAS interface
    .tcu_ras_valid             (),
    .tcu_ras_ce                (),
    .tcu_ras_ued               (),
    .tcu_ras_uec               (),
    .tcu_ras_priority          (),
    .tcu_ras_tt                (),
    .tcu_ras_scrub             (),
    .tcu_ras_ec                (),
    .tcu_ras_addr              (),
    .tcu_ras_aec               ()
);

// Clock generation
initial begin
    clk = 0;
    forever #5 clk = ~clk;  // 100MHz clock
end

// Test stimulus
initial begin
    // Initialize
    rst_n = 0;
    
    // Wait for a few clock cycles
    repeat(10) @(posedge clk);
    
    // Release reset
    rst_n = 1;
    
//     // Wait for TCU to become idle
//     wait(tcu_inst.tcu_idle);
//     $display("TCU is idle at time %0t", $time);
    
//     // Simple test: send an instruction fetch request
//     @(posedge clk);
//     tcu_inst.icu_tcu_req_vld_m1 = 1'b1;
//     tcu_inst.icu_tcu_req_addr_m1 = 20'h1000;
//     tcu_inst.icu_tcu_req_route_m1 = 3'h1;
//     tcu_inst.icu_tcu_req_id_m1 = 2'h0;
    
//     // Wait for ready
//     @(posedge clk);
//     while(!tcu_inst.tcu_icu_req_rdy_m1) @(posedge clk);
    
//     // Clear request
//     tcu_inst.icu_tcu_req_vld_m1 = 1'b0;
    
//     // Wait for response
//     repeat(5) @(posedge clk);
    
//     // Simple test: send a load request
//     @(posedge clk);
//     tcu_inst.lsu_tcu_ld_req_valid_m1[0] = 1'b1;
//     tcu_inst.lsu_tcu_ld_req_addr_m1[0] = 20'h2000;
//     tcu_inst.lsu_tcu_ld_req_route_m1[0] = 4'h2;
//     tcu_inst.lsu_tcu_ld_req_size_m1[0] = 2'h2;  // 32-bit
//     tcu_inst.lsu_tcu_ld_req_lsqid_m1[0] = 6'h1;
    
//     // Wait for ready
//     @(posedge clk);
//     while(!tcu_inst.tcu_lsu_ld_req_ready_m1[0]) @(posedge clk);
    
//     // Clear request
//     tcu_inst.lsu_tcu_ld_req_valid_m1[0] = 1'b0;
    
//     // Wait for response
//     repeat(10) @(posedge clk);
    
//     // Simple test: send a store request
//     @(posedge clk);
//     tcu_inst.sbu_tcu_req_vld = 1'b1;
//     tcu_inst.sbu_tcu_req_addr = 20'h3000;
//     tcu_inst.sbu_tcu_req_route = 4'h3;
//     tcu_inst.sbu_tcu_req_wdata = 64'hAABBCCDD11223344;
//     tcu_inst.sbu_tcu_req_wstrb = 8'hFF;
//     tcu_inst.sbu_tcu_req_atop = 6'h0;
//     tcu_inst.sbu_tcu_req_id = 6'h2;
    
//     // Wait for ready
//     @(posedge clk);
//     while(!tcu_inst.tcu_sbu_req_rdy) @(posedge clk);
    
//     // Clear request
//     tcu_inst.sbu_tcu_req_vld = 1'b0;
    
//     // Wait for response
//     repeat(10) @(posedge clk);
    
//     // End simulation
//     $display("Test completed at time %0t", $time);
//     $finish;
// end

// // Monitor TCU idle signal
// always @(posedge clk) begin
//     if (tcu_inst.tcu_idle) begin
//         $display("TCU idle signal asserted at time %0t", $time);
//     end
// end

// // Monitor responses
// always @(posedge clk) begin
//     if (tcu_inst.tcu_icu_rsp_vld_m2) begin
//         $display("ICU response received at time %0t: data=0x%h, id=%d", 
//                  $time, tcu_inst.tcu_icu_rsp_data_m2, tcu_inst.tcu_icu_rsp_id_m2);
//     end
    
//     if (tcu_inst.tcu_lsu_ld_rsp_valid_m2[0]) begin
//         $display("LSU load response received at time %0t: data=0x%h, lsqid=%d", 
//                  $time, tcu_inst.tcu_lsu_ld_rsp_data_m2[0], tcu_inst.tcu_lsu_ld_rsp_lsqid_m2[0]);
//     end
    
//     if (tcu_inst.tcu_sbu_rsp_vld) begin
//         $display("SBU store response received at time %0t: id=%d", 
//                  $time, tcu_inst.tcu_sbu_rsp_id);
//     end
end

initial begin
#250000 $finish();   //vcs simulate time finish
end

initial begin
    $fsdbDumpfile("novas.fsdb");
    $fsdbDumpvars();
    $fsdbDumpMDA();
end

endmodule 